package com.techsoul.module.pms.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.techsoul.common.core.exception.ExcelException;
import com.techsoul.common.core.pojo.vo.UserVo;
import com.techsoul.common.core.util.ServletUtils;
import com.techsoul.common.core.exception.ParamException;
import com.techsoul.common.core.util.bean.BeanUtils;
import com.techsoul.common.core.util.collection.ListUtils;
import com.techsoul.common.core.util.http.HttpClientUtils;
import com.techsoul.common.core.util.id.IdWorker;
import com.techsoul.common.core.util.lang.NumberUtils;
import com.techsoul.common.core.util.lang.StringUtils;
import com.techsoul.common.core.util.poi.ExcelImport;
import com.techsoul.common.security.service.TokenService;
import com.techsoul.module.pms.enmus.LocationStatusEnum;
import com.techsoul.module.pms.mapper.TbWmsLocationMapper;
import com.techsoul.module.pms.mapper.TbWmsMaterialInLocationMapper;
import com.techsoul.module.pms.mapper.TbWmsMaterialReceiptLineMapper;
import com.techsoul.module.pms.pojo.entity.TbWmsLocation;
import com.techsoul.module.pms.pojo.entity.TbWmsMaterialInLocation;
import com.techsoul.module.pms.pojo.entity.TbWmsMaterialReceiptLine;
import com.techsoul.module.pms.pojo.param.TbWmsLocationSaveParam;
import com.techsoul.module.pms.pojo.param.TbWmsLocationSearchParam;
import com.techsoul.module.pms.pojo.vo.TWhWarehouseVo;
import com.techsoul.module.pms.pojo.vo.TbWmsLocationVo;
import com.techsoul.module.pms.pojo.vo.TbWmsMaterialReceiptLineVo;
import com.techsoul.module.pms.service.ITWhWarehouseService;
import com.techsoul.module.pms.service.ITbWmsLocationService;
import com.techsoul.module.system.service.IConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 库区 Service实现
 *
 * @author liuen
 * @date 2022-01-25
 */

@Slf4j
@Service
@Transactional(readOnly = true)
public class TbWmsLocationServiceImpl implements ITbWmsLocationService {

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private TbWmsLocationMapper mapper;
    @Autowired
    private TbWmsMaterialReceiptLineMapper tbWmsMaterialReceiptLineMapper;

    @Autowired
    private TbWmsMaterialInLocationMapper tbWmsMaterialInLocationMapper;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private IConfigService sysConfigService;


    @Autowired
    private ITWhWarehouseService iTWhWarehouseService;
    /**
     * 新增
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String insert(TbWmsLocationSaveParam params) {
        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        TbWmsLocation entity = new TbWmsLocation();
        BeanUtils.copyProperties(params, entity);
        entity.setId(idWorker.nextId() + "").preInsert(sysUser.getId());
        this.mapper.insert(entity);
        return entity.getId();
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer delete(String id) {
        return this.mapper.deleteById(id);
    }
    @Transactional(readOnly = false)
    @Override
    public String inWareHouse(String locationNo) {
        String rst = "success";
        this.autoWarehouseDeposit(locationNo,"0");
        return rst;
    }

    @Transactional(readOnly = false)
    @Override
    public String outWareHouse(String locationNo) {
        String rst = "success";
        this.autoWarehouseFetch(locationNo,"0");
        return rst;
    }
    @Transactional(readOnly = false)
    @Override
    public String inLoc(TbWmsLocation tbWmsLocation, TbWmsMaterialReceiptLineVo tbWmsMaterialReceiptLineVo){
        String rst = "success";

        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();

            TbWmsMaterialInLocation tbWmsMaterialInLocation = new TbWmsMaterialInLocation();
            tbWmsMaterialInLocation.setBatchNo(tbWmsMaterialReceiptLineVo.getBatchNo());
            tbWmsMaterialInLocation.setCustomerId(tbWmsMaterialReceiptLineVo.getCustomerNo());
            tbWmsMaterialInLocation.setCustomerNo(tbWmsMaterialReceiptLineVo.getCustomerNo());
            tbWmsMaterialInLocation.setLocationNo(tbWmsLocation.getLocationNo());
            tbWmsMaterialInLocation.setLotNo(tbWmsLocation.getBin());
            tbWmsMaterialInLocation.setArea(tbWmsLocation.getArea());
            tbWmsMaterialInLocation.setBay(tbWmsLocation.getBay());
            tbWmsMaterialInLocation.setBin(tbWmsLocation.getBin());
            tbWmsMaterialInLocation.setTier(tbWmsLocation.getTier());
            tbWmsMaterialInLocation.setLane(tbWmsLocation.getLane());
            tbWmsMaterialInLocation.setUnitName(tbWmsMaterialReceiptLineVo.getMeasUnitNo());
            tbWmsMaterialInLocation.setCaseNo(tbWmsMaterialReceiptLineVo.getOrderNo());
            tbWmsMaterialInLocation.setWarehouseCode(tbWmsLocation.getWarehouseCode());
            tbWmsMaterialInLocation.setMaterialNo(tbWmsMaterialReceiptLineVo.getMaterialNo());
            tbWmsMaterialInLocation.setMaterialName(tbWmsMaterialReceiptLineVo.getMaterialName());
            tbWmsMaterialInLocation.setQuantity(tbWmsMaterialReceiptLineVo.getQuantity());
            tbWmsMaterialInLocation.setStatus(tbWmsMaterialReceiptLineVo.getStatus());
            tbWmsMaterialInLocation.setSiteCode(tbWmsMaterialReceiptLineVo.getSite());
            tbWmsMaterialInLocation.setRfid(tbWmsMaterialReceiptLineVo.getRfidCode());
            tbWmsMaterialInLocation.setValidityDate(new Date());

            if(tbWmsMaterialInLocation.getLocationNo().contains("CB")){
                tbWmsMaterialInLocation.setDeviceCode("11111111");
            }else  if(tbWmsMaterialInLocation.getLocationNo().contains("CC")){
                tbWmsMaterialInLocation.setDeviceCode("22222222");
            }else{
                tbWmsMaterialInLocation.setDeviceCode("11111111");
            }
            tbWmsMaterialInLocation.setFeature(tbWmsMaterialReceiptLineVo.getShipByPackOrqty());
            tbWmsMaterialInLocation.setId(idWorker.nextId() + "").preInsert(sysUser.getId());
            this.tbWmsMaterialInLocationMapper.insert(tbWmsMaterialInLocation);
            TbWmsLocation needupdatetbWmsLot =this.mapper.findByLocationNo(tbWmsLocation.getLocationNo());
            if(tbWmsMaterialReceiptLineVo.getWeight()!=null){
                if(needupdatetbWmsLot.getCurrentLoad()==null){
                    needupdatetbWmsLot.setCurrentLoad(0.0);
                }
                Double currentlocationload = needupdatetbWmsLot.getCurrentLoad();
                Double totload = NumberUtils.add(currentlocationload,tbWmsMaterialReceiptLineVo.getWeight());
                needupdatetbWmsLot.setCurrentLoad(totload);
                Double rmload = NumberUtils.sub(needupdatetbWmsLot.getMaxLoad(),totload);
                needupdatetbWmsLot.setRemainLoad(rmload);
            }
            // BeanUtils.copyProperties(tbWmsLot, needupdatetbWmsLot);
            needupdatetbWmsLot.setStatus(LocationStatusEnum.occupy.getValue());
            needupdatetbWmsLot.preUpdate(sysUser.getId());
            this.mapper.updateById(needupdatetbWmsLot);


        return rst;
    }
    @Transactional(readOnly = false)
    @Override
    public String inLoc(TbWmsLocationSaveParam params) {
        String rst = "success";
        List<String> itemIds = params.getItemList();
        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        for(int i=0;i<itemIds.size();i++){
             TbWmsMaterialReceiptLineVo tbWmsMaterialReceiptLineVo =
                     this.tbWmsMaterialReceiptLineMapper.findById(itemIds.get(i));
            TbWmsMaterialInLocation tbWmsMaterialInLocation = new TbWmsMaterialInLocation();
            tbWmsMaterialInLocation.setBatchNo(tbWmsMaterialReceiptLineVo.getBatchNo());
            tbWmsMaterialInLocation.setCustomerId(tbWmsMaterialReceiptLineVo.getCustomerNo());
            tbWmsMaterialInLocation.setCustomerNo(tbWmsMaterialReceiptLineVo.getCustomerNo());
            tbWmsMaterialInLocation.setLocationNo(params.getLocationNo());
            tbWmsMaterialInLocation.setLotNo(params.getBin());
            tbWmsMaterialInLocation.setArea(params.getArea());
            tbWmsMaterialInLocation.setBay(params.getBay());
            tbWmsMaterialInLocation.setBin(params.getBin());
            tbWmsMaterialInLocation.setTier(params.getTier());
            tbWmsMaterialInLocation.setLane(params.getLane());
            tbWmsMaterialInLocation.setUnitName(tbWmsMaterialReceiptLineVo.getMeasUnitNo());
            tbWmsMaterialInLocation.setCaseNo(tbWmsMaterialReceiptLineVo.getOrderNo());
            tbWmsMaterialInLocation.setWarehouseCode(params.getWarehouseCode());
            tbWmsMaterialInLocation.setMaterialNo(tbWmsMaterialReceiptLineVo.getMaterialNo());
            tbWmsMaterialInLocation.setMaterialName(tbWmsMaterialReceiptLineVo.getMaterialName());
            tbWmsMaterialInLocation.setQuantity(tbWmsMaterialReceiptLineVo.getQuantity());
            tbWmsMaterialInLocation.setStatus(tbWmsMaterialReceiptLineVo.getStatus());
            tbWmsMaterialInLocation.setSiteCode(tbWmsMaterialReceiptLineVo.getSite());
            tbWmsMaterialInLocation.setRfid(tbWmsMaterialReceiptLineVo.getRfidCode());
            tbWmsMaterialInLocation.setValidityDate(new Date());

            if(tbWmsMaterialInLocation.getLocationNo().contains("CB")){
                tbWmsMaterialInLocation.setDeviceCode("11111111");
            }else  if(tbWmsMaterialInLocation.getLocationNo().contains("CC")){
                tbWmsMaterialInLocation.setDeviceCode("22222222");
            }else{
                tbWmsMaterialInLocation.setDeviceCode("11111111");
            }
            tbWmsMaterialInLocation.setFeature(tbWmsMaterialReceiptLineVo.getShipByPackOrqty());
             tbWmsMaterialInLocation.setId(idWorker.nextId() + "").preInsert(sysUser.getId());
            this.tbWmsMaterialInLocationMapper.insert(tbWmsMaterialInLocation);
            TbWmsLocation needupdatetbWmsLot =this.mapper.findByLocationNo(params.getLocationNo());
            if(tbWmsMaterialReceiptLineVo.getWeight()!=null){
                if(needupdatetbWmsLot.getCurrentLoad()==null){
                    needupdatetbWmsLot.setCurrentLoad(0.0);
                }
                Double currentlocationload = needupdatetbWmsLot.getCurrentLoad();
                Double totload = NumberUtils.add(currentlocationload,tbWmsMaterialReceiptLineVo.getWeight());
                needupdatetbWmsLot.setCurrentLoad(totload);
                Double rmload = NumberUtils.sub(needupdatetbWmsLot.getMaxLoad(),totload);
                needupdatetbWmsLot.setRemainLoad(rmload);
            }

            // BeanUtils.copyProperties(tbWmsLot, needupdatetbWmsLot);
            needupdatetbWmsLot.setStatus(LocationStatusEnum.occupy.getValue());
            needupdatetbWmsLot.preUpdate(sysUser.getId());
            this.mapper.updateById(needupdatetbWmsLot);
        }

        return rst;
    }
    /**
     * 存货处理
     * @param locationNo
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String autoWarehouseDeposit(String locationNo,String inboundOrderNo){
        JSONObject params = new JSONObject();
        JSONObject data = new JSONObject();
        data.put("Location",locationNo);
        data.put("Url", "http://192.168.1.15:39527/api/StorageDepositCallback");
        data.put("Id",inboundOrderNo);
        params.put("Status", 1);
        params.put("ErrorCode", 200);
        params.put("ErrorMsg", "成功");
        params.put("Data", data);
        String SignatureUrl = sysConfigService.findByConfigKey("Deposite.url");
        String resp = HttpClientUtils.ajaxPostJson(SignatureUrl, JSONObject.toJSONString(params));
     /*   JSONObject respObj = JSONObject.parseObject(resp);
        if (respObj.getInteger("ErrorCode") == 200) {
            log.info("调用存料接口成功");
        } else {
            log.error("调用存料接口失败，错误原因：{}", respObj.getString("ErrorMsg"));
        }*/

        return "success";
    }
    /**
     * 取货处理
     * @param locationNo
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String autoWarehouseFetch(String locationNo,String orderNo){
        JSONObject params = new JSONObject();
        JSONObject data = new JSONObject();
        data.put("Location",locationNo);
        data.put("Url", "http://192.168.1.15:39527/api/StorageFetchCallback");
        data.put("Id",orderNo);
        params.put("Status", 1);
        params.put("ErrorCode", 200);
        params.put("ErrorMsg", "成功");
        params.put("Data", data);
        String SignatureUrl = sysConfigService.findByConfigKey("Fetch.url");
        String resp = HttpClientUtils.ajaxPostJson(SignatureUrl, JSONObject.toJSONString(params));
      /*  JSONObject respObj = JSONObject.parseObject(resp);
        if (respObj.getInteger("ErrorCode") == 200) {
            log.info("调用取料接口成功");
        } else {
            log.error("调用取料接口失败，错误原因：{}", respObj.getString("ErrorMsg"));
        }*/

        return "success";
    }
    /**
     * 批量删除
     * @param idList
     */
    @Transactional(readOnly = false)
    @Override
    public Integer batchDelete(List<String> idList) {
        if (ListUtils.isNotEmpty(idList)) {
            return this.mapper.deleteBatchIds(idList);
        } else {
            return 0;
        }
    }

    /**
     * 修改
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer update(TbWmsLocationSaveParam params) {
        TbWmsLocation entityFromDb = this.mapper.selectById(params.getId());
        if (entityFromDb == null) {
            throw new ParamException("id=" + params.getId());
        }
        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        BeanUtils.copyProperties(params, entityFromDb);
        entityFromDb.preUpdate(sysUser.getId());
        return this.mapper.updateById(entityFromDb);
    }

    /**
     * 详情
     * @param id
     * @return
     */
    @Override
    public TbWmsLocationVo findById(String id) {
        return this.mapper.findById(id);
    }

    /**
     * 列表
     * @param params
     * @return
     */
    @Override
    public List<TbWmsLocationVo> findAll(TbWmsLocationSearchParam params) {
        return this.mapper.findAll(params);
    }

    /**
     * 列表-分页
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<TbWmsLocationVo> findAll(TbWmsLocationSearchParam params, Integer current, Integer pageSize) {
        return this.mapper.findAll(new Page<>(current, pageSize), params);
    }
    /**
     * 导入
     * @param file
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String importData(String warehouseNo, MultipartFile file) {
        List<TbWmsLocationVo> dataList = null;
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        TWhWarehouseVo warehouseVo = iTWhWarehouseService.findById(warehouseNo);

        int successNum = 0;
        int failureNum = 0;
        int logNum = 0;
        try {
            ExcelImport excelImport = new ExcelImport(file, 1, 0);
            dataList = excelImport.getDataList(TbWmsLocationVo.class);
        } catch (Exception e) {
            log.error("获取数据信息失败!");
            throw new ExcelException("获取数据信息失败!");
        }
        if (ListUtils.isEmpty(dataList)) {
            throw new ExcelException("导入数据不能为空！");
        }

        if(dataList==null||dataList.size()==0){
            return "没有读取到数据";
        }
        TbWmsLocationVo firstdata = (TbWmsLocationVo)dataList.get(0);
        String custOrderNo ="";

        int itemNo = 0;
        int line = 0;
        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        for (TbWmsLocationVo data : dataList) {
            data = this.removeSpecialChar(data);
            TbWmsLocation tbWmsLocation = new TbWmsLocation();
            BeanUtils.copyProperties(data, tbWmsLocation);
            if(StringUtils.isNull(data.getArea())||data.getArea()==""){
                if(warehouseNo.equals("1")){
                    tbWmsLocation.setLocationType("智能物品区");
                    tbWmsLocation.setArea("智能物品区");
                }else if(warehouseNo.equals("3")){
                    tbWmsLocation.setLocationType("贵重物品区");
                    tbWmsLocation.setArea("贵重物品区");
                }else if(warehouseNo.equals("2")){
                    tbWmsLocation.setLocationType("普通物品区");
                    tbWmsLocation.setArea("普通物品区");
                }else if(warehouseNo.equals("4")){
                    tbWmsLocation.setLocationType("重型物品区");
                    tbWmsLocation.setArea("重型物品区");
                }else if(warehouseNo.equals("5")){
                    tbWmsLocation.setLocationType("超规物品区");
                    tbWmsLocation.setArea("超规物品区");
                }else{
                    tbWmsLocation.setLocationType("普通物品区");
                    tbWmsLocation.setArea("普通物品区");
                }

            }else{
                tbWmsLocation.setLocationType(data.getArea());

            }
            String locNo = tbWmsLocation.getLocationNo();
            String savelocno = locNo.substring(0,2).concat("-").concat(locNo.substring(2,4).concat("-")
            .concat(locNo.substring(4,6)).concat("-").concat(locNo.substring(6)));
            tbWmsLocation.setLocationNo(savelocno);
            tbWmsLocation.setWarehouseCode(warehouseNo);
            tbWmsLocation.setId(idWorker.nextId() + "").preInsert(sysUser.getId());
            this.mapper.insert(tbWmsLocation);

            successNum= successNum++;



        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误清查日志");

            return "操作有"+failureNum+"行输入异常，请看日志";
        } else {
            if(logNum>0){
                successMsg.insert(0, "恭喜您，操作成功！共 " + successNum + " 条，另有：" +logNum+ " 条数据不能正常导入，已写入日志");

            }else{
                successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");

            }
        }
        return successMsg.toString();
    }


    public TbWmsLocationVo removeSpecialChar(TbWmsLocationVo input){
        Pattern p =null;
        Matcher m = null;;
        String rt = "";


        //spu
        if(!StringUtils.isNull(input.getLocationNo())) {
            p = Pattern.compile("\\s*|\t|\r|\n");
            m = p.matcher(input.getLocationNo());
            rt = m.replaceAll("");
            input.setLocationNo(rt);
        }
        if(!StringUtils.isNull(input.getLocationName())) {
            p = Pattern.compile("\\s*|\t|\r|\n");
            m = p.matcher(input.getLocationName());
            rt = m.replaceAll("");
            input.setLocationName(rt);
        }
        if(!StringUtils.isNull(input.getLocationType())) {
            p = Pattern.compile("\t");
            m = p.matcher(input.getLocationType());
            rt = m.replaceAll("");
            input.setLocationType(rt);
        }
        if(!StringUtils.isNull(input.getWarehouseCode())) {
            p = Pattern.compile("\\s*|\t|\r|\n");
            m = p.matcher(input.getWarehouseCode());
            rt = m.replaceAll("");
            input.setWarehouseCode(rt);
        }




        return input;
    }
}
